package com.md.drcs.dicom.service.impl;

import com.md.common.exception.BaseBizException;
import com.md.common.exception.BaseErrorCode;
import com.md.drcs.dicom.dao.PatientDao;
import com.md.drcs.dicom.dao.ReportDao;
import com.md.drcs.dicom.dao.StudyDao;
import com.md.drcs.dicom.dao.UserPatientDao;
import com.md.drcs.dicom.dto.StudyBasicInfoDTO;
import com.md.drcs.dicom.dto.StudyDetailDTO;
import com.md.drcs.dicom.dto.UserPatientDTO;
import com.md.drcs.dicom.entity.PatientEntity;
import com.md.drcs.dicom.entity.ReportEntity;
import com.md.drcs.dicom.entity.StudyEntity;
import com.md.drcs.dicom.entity.UserPatientEntity;
import com.md.drcs.dicom.req.AddUserPatientReq;
import com.md.drcs.dicom.service.UserPatientService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class UserPatientServiceImpl implements UserPatientService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserPatientService.class);

    @Autowired
    private StudyDao studyDao;

    @Autowired
    private PatientDao patientDao;

    @Autowired
    private UserPatientDao userPatientDao;

    @Autowired
    private ReportDao reportDao;

//    @Value("${study.report-pdf.server}")
    private String reportPDFServer;

//    @Value("${study.report.path}")
    private String studyReportPath;

    @Override
    public List<UserPatientDTO> findByUserId(Integer userId) {
        List<UserPatientEntity> userPatients = userPatientDao.findByUserId(userId);
        List<UserPatientDTO> dtos = userPatients.stream().map(e -> studyDao.getNewestStudy(e.getPatientId())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(dtos))
            return dtos;

        try {
            List<Long> patIds = dtos.stream().map(UserPatientDTO::getnPatId).collect(Collectors.toList());
            List<PatientEntity> patients = patientDao.findByIds(patIds);
            // 可能存在nPatID不同，sPatIdInPacs相同的患者信息
            Map<String, List<PatientEntity>> patientMap = patients.stream().collect(Collectors.groupingBy(PatientEntity::getSPatIdInPacs));
            if (patients.size() != patientMap.size()) { // 通过sPatIdInPacs去重校验
                // 去除重复的患者
                List<UserPatientDTO> results = new ArrayList<>();

                Map<Long, UserPatientDTO> patMap = dtos.stream().collect(HashMap::new, (map, e) -> map.put(e.getnPatId(), e), HashMap::putAll);

                for (List<PatientEntity> pats : patientMap.values()) {
                    if (pats.size() == 1) {
                        results.add(patMap.get(pats.get(0).getNPatId()));
                        continue;
                    }
                    UserPatientDTO dto = null;
                    for (PatientEntity patient : pats) { // sPatIdInPacs重复的病人信息
                        if (dto == null)
                            dto = patMap.get(patient.getNPatId());
                        else {
                            UserPatientDTO next = patMap.get(patient.getNPatId()); // 挑选出最新一条检查信息
                            if (next.getStuDate() != null && dto.getStuDate() != null && next.getStuDate().isAfter(dto.getStuDate())) {
                                dto = next;
                            }
                        }
                    }
                    results.add(dto);
                }

                return results;
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }

        return dtos;
    }

    @Override
    public void deletePatient(Integer patientId, Integer userId) {
        userPatientDao.deletePatient(patientId, userId);
    }

    @Override
    public void add(AddUserPatientReq req) {

    }

    @Override
    public void add(Integer patientId, Integer userId) {
        UserPatientEntity record = userPatientDao.findByUserPatient(userId, patientId);
        if (record != null)
            return;
        UserPatientEntity userPatient = new UserPatientEntity();
        userPatient.setUserId(userId);
        userPatient.setPatientId(patientId);
        userPatientDao.insert(userPatient);

        try {
            // 首次绑定病人，如果改病人存在已审核为发送通知的报告，则直接修改报告为已通知
            List<StudyEntity> studies = studyDao.findNotNotifyAuditedByPatientId(patientId);
            if (!CollectionUtils.isEmpty(studies)) {
                List<Long> studyIds = studies.stream().map(StudyEntity::getNStuId).collect(Collectors.toList());
                studyDao.updateNotifyStatus(studyIds);
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e );
        }
    }

    @Override
    public UserPatientEntity findByUserPatient(Integer userId, Integer patientId) {
        return userPatientDao.findByUserPatient(userId, patientId);
    }

    @Override
    public List<StudyBasicInfoDTO> getAuditedReports() {
        return null;
    }

    @Override
    public void updateNotifyStatus(List<Long> studyIds) {
        studyDao.updateNotifyStatus(studyIds);
    }

    @Override
    public StudyDetailDTO getStudyDetail(Long id, Integer userId) {

        StudyDetailDTO dto = new StudyDetailDTO();

        StudyEntity study = studyDao.selectByPrimaryKey(id);
        if (study == null)
            throw new BaseBizException(BaseErrorCode.INVALID_DATA, "暂未查询到您的信息，请您稍后再试");
        if (study.getbCloseCloud() != 0)
            throw new BaseBizException(BaseErrorCode.INVALID_DATA, "您已打印传统胶片，电子胶片已关闭！");

        BeanUtils.copyProperties(study, dto);

        PatientEntity patient = patientDao.selectByPrimaryKey(study.getNPatID());
        dto.setPatient(patient);

       /* UserPatientEntity record = userPatientDao.findByUserPatient(userId, dto.getNPatID().intValue());

        if (record == null) {
            // 不存在绑定记录，可能检查信息的nPatId不通，但sPatIdInPacs相同
            // 获取请求查看病人的sPatIdInPacs，与绑定病人的sPatIdInPacs比较
            List<UserPatientEntity> ups = userPatientDao.findByUserId(userId);
            if (CollectionUtils.isEmpty(ups))
                throw new BaseBizException(SystemErrorCode.INVALID_DATA, "检查绑定信息错误");
            List<PatientEntity> patients = patientDao.findByIds(ups.stream().map(e -> e.getPatientId().longValue()).collect(Collectors.toList()));
            Optional<PatientEntity> any = patients.stream().filter(p -> p.getSPatIdInPacs().equalsIgnoreCase(patient.getSPatIdInPacs())).findAny();
            if (!any.isPresent()) {
                throw new BaseBizException(SystemErrorCode.INVALID_DATA, "检查绑定信息错误");
            }
        }*/

        ReportEntity report = reportDao.findByStudyId(id);
        dto.setReport(report);

        ReportEntity reportConsul = reportDao.findByStudyIdForConsul(id);
        dto.setReportConsul(reportConsul);

        if ((!StringUtils.equals(dto.getSStuStatus(), "已审核") && !StringUtils.equals(dto.getSStuStatus(), "已打印")) || report == null)
            return dto;

        if(StringUtils.isBlank(report.getSReportPath())) {
            LOGGER.debug("pdf file not exists (path is null)");
            return dto;
        }


        return dto;
    }
}
